package braden.cis.uab.edu.automaton;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;

public abstract class AbstractDrawingPanel extends SurfaceView implements SurfaceHolder.Callback{

	private DrawingThread drawingThread;
	static private ArrayList<State> graphics;
	static private ArrayList<Transition> transitions;
	private Context context;
	
	public AbstractDrawingPanel(Context context) {
		super(context);
		
		this.context = context;
		graphics = new ArrayList<State>();
		transitions = new ArrayList<Transition>();

		getHolder().addCallback(this);
		drawingThread = new DrawingThread(getHolder(), this);
		setFocusable(true);
	}

	@Override
	public void onDraw(Canvas canvas) {}
	
	public void drawAutomaton(Automaton automaton) {

		drawingThread.setRunning(false);
		graphics = automaton.getStates();
		transitions = automaton.getTransitions();
		drawingThread.setRunning(true);
	}
	
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		drawingThread.setRunning(true);
		drawingThread.start();
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {}
	
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// simply copied from sample application LunarLander:
		// we have to tell thread to shut down & wait for it to finish, or else
		// it might touch the Surface after we return and explode
		boolean retry = true;
		drawingThread.setRunning(false);
		while (retry) {
			try {
				drawingThread.join();
				retry = false;
			} catch (InterruptedException e) {
				// we will try it again and again...
			}
		}
	}
	
	// to string method for printing automaton
	public String toString() {

		String automatonString = "";
		// find the initial
		for (State graphic : graphics) {
			if (graphic.isInitial()) {
				automatonString += "initial state: " + graphic.getLabel() + "\n";
				break;
			}
		}
		if (automatonString.equals("")) {
			Toast.makeText(this.getContext(),
					"Your automaton must have an initial state.",
					Toast.LENGTH_LONG).show();
			return null;
		}
		for (State graphic : graphics) {
			automatonString += "state " + graphic.getLabel();
			if (graphic.isFinal()) {
				automatonString += " [accept]:\n";
			} else {
				automatonString += " [reject]:\n";
			}
			for (Transition transition : graphic.getTransitions()) {
				automatonString += "  ";
				String labels = "";
				for (char transitionCharacter : transition.getLabels()) {
					labels += "-" + transitionCharacter;
				}
				labels = labels.substring(1);
				automatonString += labels + " -> "
						+ transition.getEndState().getLabel() + "\n";
			}
		}
		return automatonString;
	}
	
	public Automaton getAutomaton() {
		return new Automaton(context, graphics, transitions);
	}

	public DrawingThread getDrawingThread() {
		return drawingThread;
	}

	public ArrayList<State> getGraphics() {
		return graphics;
	}

	public ArrayList<Transition> getTransitions() {
		return transitions;
	}
}